package com.zzh.custom;

import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Color;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;

import androidx.annotation.ColorRes;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import java.util.ArrayList;
import java.util.List;

/**
 * @author zhangzhihao
 * @email zhangzhihao@gongjiangren.net
 * @date 2020-09-29
 * @desc
 */
public class LevelSelectView extends DynamicSplitView {

    public interface OnSelectListener {
        void onResults(List<? extends SelectMoudle> mDatas, List<Integer> indexs);

        void onMultiCount(int count);
    }


    /**
     * 最多分为几级
     */
    private int mMaxCount = 5;

    /**
     * 多选 最多选多少个 （单选无用）
     */
    private int mMaxSelectCount = -1;
    /**
     * 是不是多选
     * 0 -> 不是多选
     * 1 -> 正常多选
     * 2 -> 设置式多选
     */
    private int multiSelect = 0;

    /**
     * 允许多选的列
     * multiSelect == 2 时有效
     */
    private List<Integer> allowMultiSelects;


    /**
     * 多选 选中的数据 （单选无用）
     */
    private List<List<Integer>> mMultiSelects;

    /**
     * 单选 选中的数据 （多选无用）
     */
    private List<Integer> mSingleSelect;


    /**
     * 数据源
     */
    private List<? extends SelectMoudle> mDatas;
    private OnSelectListener mOnSelectListener;

    public LevelSelectView(Context context) {
        super(context);
    }

    public LevelSelectView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public LevelSelectView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public void setOnSelectListener(OnSelectListener onSelectListener) {
        this.mOnSelectListener = onSelectListener;
    }


    @Override
    protected void init(Context context, AttributeSet attrs) {
        super.init(context, attrs);
    }

    private @ColorRes
    int[] mBg;
    private @ColorRes
    int[] mItemBg;
    private @ColorRes
    int[] mSelectBg;
    private @ColorRes
    int[] mTextDefault;
    private @ColorRes
    int[] mTextSelect;


    public void setDatas(List<? extends SelectMoudle> datas, int count, int defaultCount,
                         @ColorRes int[] bg,
                         @ColorRes int[] itemBg,
                         @ColorRes int[] selectBg,
                         @ColorRes int[] textDefault,
                         @ColorRes int[] textSelect) {
        if (datas == null || datas.size() <= 0) {
            // TODO: 2020-09-29 处理界面展示 
            return;
        }
        mBg = bg;
        mItemBg = itemBg;
        mSelectBg = selectBg;
        mTextDefault = textDefault;
        mTextSelect = textSelect;
        this.mDatas = datas;
        int nowCount = getChildCount();
        for (int i = nowCount; i < count; i++) {
            addListView();
        }

        if (defaultCount > 0) {
            List<? extends SelectMoudle> selectMoudles = mDatas;
            for (int i = 0; i < defaultCount; i++) {
                if (selectMoudles == null || selectMoudles.size() <= 0) {
                    break;
                }
                SelectMoudle selectMoudle = selectMoudles.get(0);
                selectMoudle.setSelect(true);
                List<? extends SelectMoudle> selectChildMoudles = selectMoudle.getChildSelectMoudles();
                setAdapterData(i,
                        selectMoudles,
                        false,
                        selectChildMoudles == null || selectChildMoudles.size() <= 0);
                ((MyAdapter) ((RecyclerView) getChildAt(i)).getAdapter()).setSelectPositon(0);
                selectMoudles = selectChildMoudles;
            }
        } else {
            if (multiSelect >= 1) {
                // 多选
                if (mMultiSelects.size() > 0) {
                    List<Integer> firstSelect = mMultiSelects.get(0);
                    List<? extends SelectMoudle> selectMoudles = mDatas;
                    for (int i = 0; i < firstSelect.size(); i++) {
                        List<? extends SelectMoudle> selectChildMoudles = selectMoudles.get(firstSelect.get(i)).getChildSelectMoudles();
                        setAdapterData(i,
                                selectMoudles,
                                false,
                                selectChildMoudles == null || selectChildMoudles.size() <= 0);
                        ((MyAdapter) ((RecyclerView) getChildAt(i)).getAdapter()).setSelectPositon(firstSelect.get(i));
                        selectMoudles = selectChildMoudles;
                    }
                } else {
                    setAdapterData(0,
                            this.mDatas,
                            false,
                            getChildCount() == 1);
                }
            } else {
                // 单选
                if (mSingleSelect != null && mSingleSelect.size() > 0) {
                    List<? extends SelectMoudle> selectMoudles = mDatas;
                    for (int i = 0; i < mSingleSelect.size(); i++) {
                        SelectMoudle selectMoudle = selectMoudles.get(mSingleSelect.get(i));
                        selectMoudle.setSelect(true);
                        boolean isIgnoreChilds = selectMoudle.isIgnoreChilds();
                        if (isIgnoreChilds) {
                            setAdapterData(i,
                                    selectMoudles,
                                    false,
                                    true);
                            ((MyAdapter) ((RecyclerView) getChildAt(i)).getAdapter()).setSelectPositon(mSingleSelect.get(i));
                            break;
                        } else {
                            List<? extends SelectMoudle> selectChildMoudles = selectMoudle.getChildSelectMoudles();
                            setAdapterData(i,
                                    selectMoudles,
                                    false,
                                    selectChildMoudles == null || selectChildMoudles.size() <= 0);
                            ((MyAdapter) ((RecyclerView) getChildAt(i)).getAdapter()).setSelectPositon(mSingleSelect.get(i));
                            selectMoudles = selectChildMoudles;
                        }
                    }
                } else {
                    setAdapterData(0,
                            this.mDatas,
                            false,
                            getChildCount() == 1);
                }
            }
        }
    }

    /**
     * 设置为多选
     *
     * @param maxSelectCount 最多选多少个
     * @return
     */
    public void setMultiSelect(int maxSelectCount, List<List<Integer>> multiSelects, List<Integer> allowMultiSelects) {
        setMultiSelects(multiSelects);
        this.mMaxSelectCount = maxSelectCount;
        this.allowMultiSelects = allowMultiSelects;
        this.multiSelect = (allowMultiSelects == null || allowMultiSelects.size() < 0) ? 1 : 2;
        for (int i = 0; i < getChildCount(); i++) {
            MyAdapter myAdapter = ((MyAdapter) ((RecyclerView) getChildAt(i)).getAdapter());
            if (!myAdapter.isMultiSelect) {
                myAdapter.setMultiSelect(true);
                myAdapter.setSelectCountStatus(new MyAdapter.SelectCountStatus() {
                    @Override
                    public boolean isMax() {
                        return mMultiSelects.size() >= mMaxSelectCount;
                    }

                    @Override
                    public int getMaxCount() {
                        return mMaxSelectCount;
                    }
                });
            }
        }
    }

    public void setSingleSelect(List<Integer> singleSelect) {
        this.mSingleSelect = singleSelect;
    }

    private void setMultiSelects(List<List<Integer>> multiSelects) {
        this.mMultiSelects = multiSelects;
        if (mMultiSelects == null) {
            this.mMultiSelects = new ArrayList<>();
        }
    }


    public List<List<Integer>> getMultiSelectIndexs() {
        return mMultiSelects;
    }


    public List<? extends SelectMoudle> getDatas() {
        return mDatas;
    }

    private void setAdapterData(final int childIndex, final List<? extends SelectMoudle> selectMoudles, boolean isAnimator, boolean isEnd) {
        if (multiSelect >= 1) {
            for (int i = 0; i < selectMoudles.size(); i++) {
                selectMoudles.get(i).setSelect(false);
                for (List<Integer> select : mMultiSelects) {
                    int selectSize = select.size();
                    if (selectSize >= childIndex + 1) {
                        // 当前点击列
                        boolean isParentSelesct = true;
                        for (int index = childIndex - 1; index >= 0; index--) {
                            if (((MyAdapter) ((RecyclerView) getChildAt(index)).getAdapter()).getSelectIndex() != select.get(index)) {
                                isParentSelesct = false;
                                break;
                            }
                        }
                        if (isParentSelesct && select.get(childIndex) == i) {
                            selectMoudles.get(i).setSelect(true);
                        }
                    }
                }
            }
            if (childIndex > 0 && !isEnd) {
                RecyclerView recyclerView = (RecyclerView) getChildAt(childIndex - 1);
                MyAdapter myAdapter = (MyAdapter) recyclerView.getAdapter();
                List<? extends SelectMoudle> list = myAdapter.getList();
                for (int i = 0; i < list.size(); i++) {
                    list.get(i).setSelect(myAdapter.getSelectIndex() == i);
                    for (List<Integer> select : mMultiSelects) {
                        int selectSize = select.size();
                        if (selectSize >= childIndex) {
                            // 当前点击列
                            boolean isParentSelesct = true;
                            for (int index = childIndex - 2; index >= 0; index--) {
                                if (((MyAdapter) ((RecyclerView) getChildAt(index)).getAdapter()).getSelectIndex() != select.get(index)) {
                                    isParentSelesct = false;
                                    break;
                                }
                            }
                            if (isParentSelesct && select.get(childIndex - 1) == i) {
                                list.get(i).setSelect(true);
                            }
                        }
                    }
                }
                myAdapter.setList(list);
                myAdapter.notifyDataSetChanged();
            }
        }
        RecyclerView recyclerView = (RecyclerView) getChildAt(childIndex);
        MyAdapter myAdapter = (MyAdapter) recyclerView.getAdapter();
        myAdapter.setList(selectMoudles);
        myAdapter.notifyDataSetChanged();
        setShowCount(childIndex + 1, isAnimator ? null : (ValueAnimator.AnimatorUpdateListener) animation -> {
        });
    }

    /**
     * 添加一个listview
     */
    private void addListView() {
        if (getChildCount() > mMaxCount) {
            throw new IndexOutOfBoundsException("添加数量超出范围");
        }
        RecyclerView recyclerView = new RecyclerView(getContext());
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        final MyAdapter myAdapter = new MyAdapter(getChildCount(), (myAdapter12, childIndex, selectPosition) -> {
            List<? extends SelectMoudle> list = myAdapter12.getSelectMoudle().getChildSelectMoudles();
            if (multiSelect >= 1) {
                // 多选
                if (multiSelect == 1) {
                    // 所有列都可多选
                    if (list == null || list.size() <= 0) {
                        List<Integer> integers = null;
                        for (List<Integer> mMultiSelect : mMultiSelects) {
                            if (mMultiSelect.size() == childIndex + 1 && mMultiSelect.get(childIndex) == selectPosition) {
                                boolean isSelect = true;
                                for (int index = childIndex - 1; index >= 0; index--) {
                                    if (((MyAdapter) ((RecyclerView) getChildAt(index)).getAdapter()).getSelectIndex() != mMultiSelect.get(index)) {
                                        isSelect = false;
                                        break;
                                    }
                                }
                                if (isSelect) {
                                    integers = mMultiSelect;
                                    break;
                                }
                            }
                        }
                        if (integers != null) {
                            mMultiSelects.remove(integers);
                        } else {
                            integers = new ArrayList<>();
                            for (int i = 0; i <= childIndex; i++) {
                                integers.add(((MyAdapter) ((RecyclerView) getChildAt(i)).getAdapter()).getSelectIndex());
                            }
                            mMultiSelects.add(integers);
                        }
                        if (mOnSelectListener != null) {
                            mOnSelectListener.onMultiCount(mMultiSelects.size());
                        }
                        setAdapterData(childIndex, myAdapter12.getList(), true, true);
                    } else {
                        // 执行扩展一级
                        setAdapterData(childIndex + 1, list, true, false);
                    }
                } else if (multiSelect == 2) {
                    // 指定列可以多选
                    if (allowMultiSelects.contains(childIndex)) {
                        // 允许多选
                        if (list == null || list.size() <= 0) {
                            List<Integer> integers = null;
                            for (List<Integer> mMultiSelect : mMultiSelects) {
                                if (mMultiSelect.size() == childIndex + 1 && mMultiSelect.get(childIndex) == selectPosition) {
                                    boolean isSelect = true;
                                    for (int index = childIndex - 1; index >= 0; index--) {
                                        if (((MyAdapter) ((RecyclerView) getChildAt(index)).getAdapter()).getSelectIndex() != mMultiSelect.get(index)) {
                                            isSelect = false;
                                            break;
                                        }
                                    }
                                    if (isSelect) {
                                        integers = mMultiSelect;
                                        break;
                                    }
                                }
                            }
                            if (integers != null) {
                                mMultiSelects.remove(integers);
                            } else {
                                integers = new ArrayList<>();
                                for (int i = 0; i <= childIndex; i++) {
                                    integers.add(((MyAdapter) ((RecyclerView) getChildAt(i)).getAdapter()).getSelectIndex());
                                }
                                mMultiSelects.add(integers);
                            }
                            if (mOnSelectListener != null) {
                                mOnSelectListener.onMultiCount(mMultiSelects.size());
                            }
                            setAdapterData(childIndex, myAdapter12.getList(), true, true);
                        } else {
                            // 执行扩展一级
                            setAdapterData(childIndex + 1, list, true, false);
                        }
                    } else {
                        // 不允许多选
                        List<List<Integer>> integers = new ArrayList<>();
                        List<Integer> selectInteger = null;

                        int selectIndex = ((MyAdapter) ((RecyclerView) getChildAt(childIndex)).getAdapter()).getSelectIndex();
                        for (List<Integer> mMultiSelect : mMultiSelects) {
                            if (mMultiSelect.size() > childIndex) {
                                if (mMultiSelect.get(childIndex) == selectIndex) {
                                    selectInteger = mMultiSelect;
                                } else {
                                    integers.add(mMultiSelect);
                                }
                            }
                        }
                        if (integers.size() > 0) {
                            mMultiSelects.removeAll(integers);
                        }
                        if (selectInteger != null) {
                            mMultiSelects.remove(selectInteger);
                        } else {
                            if (list == null || list.size() <= 0) {
                                selectInteger = new ArrayList<>();
                                for (int i = 0; i <= childIndex; i++) {
                                    selectInteger.add(((MyAdapter) ((RecyclerView) getChildAt(i)).getAdapter()).getSelectIndex());
                                }
                                mMultiSelects.add(selectInteger);
                            }
                        }
                        if (mOnSelectListener != null) {
                            mOnSelectListener.onMultiCount(mMultiSelects.size());
                        }
                        if (list == null || list.size() <= 0) {
                            setAdapterData(childIndex, myAdapter12.getList(), true, true);
                        } else {
                            // TODO: 2020-10-16 有问题
                            // 执行扩展一级
                            setAdapterData(childIndex + 1, list, true, false);
                        }
                    }
                } else {
                    throw new IllegalArgumentException("模式错误");
                }

            } else {
                boolean isIgnoreChilds = myAdapter12.getSelectMoudle().isIgnoreChilds();
                List<? extends SelectMoudle> selectMoudles = myAdapter12.getList();
                if (isIgnoreChilds) {
                    // 执行确定
                    List<Integer> indexs = new ArrayList<>();
                    for (int i = 0; i <= childIndex; i++) {
                        RecyclerView recyclerView1 = (RecyclerView) getChildAt(i);
                        MyAdapter myAdapter1 = (MyAdapter) recyclerView1.getAdapter();
                        indexs.add(myAdapter1.getSelectIndex());
                    }
                    int childCount = getChildCount();
                    for (int i = childIndex + 1; i < childCount; i++) {
                        if (selectMoudles != null && selectMoudles.size() > 0) {
                            indexs.add(0);
                            continue;
                        }
                        break;
                    }
                    if (mOnSelectListener != null) {
                        mOnSelectListener.onResults(mDatas, indexs);
                    }
                } else {
                    // 单选
                    if (list == null || list.size() <= 0) {
                        // 执行确定
                        List<Integer> indexs = new ArrayList<>();
                        for (int i = 0; i <= childIndex; i++) {
                            RecyclerView recyclerView1 = (RecyclerView) getChildAt(i);
                            MyAdapter myAdapter1 = (MyAdapter) recyclerView1.getAdapter();
                            indexs.add(myAdapter1.getSelectIndex());
                        }
                        if (mOnSelectListener != null) {
                            mOnSelectListener.onResults(mDatas, indexs);
                        }
                    } else {
                        // 执行扩展一级
                        setAdapterData(childIndex + 1, list, true, false);
                    }
                }
            }
        });
        if (multiSelect >= 1) {
            myAdapter.setMultiSelect(true);
            myAdapter.setSelectCountStatus(new MyAdapter.SelectCountStatus() {
                @Override
                public boolean isMax() {
                    return mMultiSelects.size() >= mMaxSelectCount;
                }

                @Override
                public int getMaxCount() {
                    return mMaxSelectCount;
                }
            });
        }
        Resources resources = getContext().getResources();
        myAdapter.setDefaultBgColor(mItemBg == null ? -1 : resources.getColor(mItemBg[getChildCount()]));
        myAdapter.setSelectTextColor(mTextSelect == null ? -1 : resources.getColor(mTextSelect[getChildCount()]));
        myAdapter.setSelectBgColor(mSelectBg == null ? -1 : resources.getColor(mSelectBg[getChildCount()]));
        myAdapter.setDefaultTextColor(mTextDefault == null ? -1 : resources.getColor(mTextDefault[getChildCount()]));
        recyclerView.setAdapter(myAdapter);
        recyclerView.setBackgroundColor(mBg == null ? null : resources.getColor(mBg[getChildCount()]));
        addView(recyclerView);
    }


    public static class MyAdapter extends RecyclerView.Adapter<MyViewHolder> {


        interface MyAdapterClickListener {
            void onClick(MyAdapter myAdapter, int childIndex, int selectPosition);
        }

        interface SelectCountStatus {
            boolean isMax();

            int getMaxCount();
        }

        private List<? extends SelectMoudle> list;
        private Context mContext;
        private int childIndex;
        private boolean isMultiSelect = false;
        private MyAdapterClickListener myAdapterClickListener;
        private SelectCountStatus selectCountStatus;
        private int selectBgColor = Color.RED;
        private int selectTextColor = Color.BLACK;
        private int defaultBgColor = Color.TRANSPARENT;
        private int defaultTextColor = Color.GRAY;

        public void setSelectBgColor(int selectBgColor) {
            this.selectBgColor = selectBgColor == -1 ? Color.RED : selectBgColor;
        }

        public void setSelectTextColor(int selectTextColor) {
            this.selectTextColor = selectTextColor == -1 ? Color.BLACK : selectTextColor;
        }

        public void setDefaultBgColor(int defaultBgColor) {
            this.defaultBgColor = defaultBgColor == -1 ? Color.TRANSPARENT : defaultBgColor;
        }

        public void setDefaultTextColor(int defaultTextColor) {
            this.defaultTextColor = defaultTextColor == -1 ? Color.GRAY : defaultTextColor;
        }

        public void setMultiSelect(boolean multiSelect) {
            isMultiSelect = multiSelect;
        }

        public boolean isMultiSelect() {
            return isMultiSelect;
        }

        private int mSelectPositon = -1;

        public void setSelectPositon(int selectPositon) {
            this.mSelectPositon = selectPositon;
        }

        public MyAdapter(int childIndex, MyAdapterClickListener myAdapterClickListener) {
            this.childIndex = childIndex;
            this.myAdapterClickListener = myAdapterClickListener;
        }

        public void setSelectCountStatus(SelectCountStatus selectCountStatus) {
            this.selectCountStatus = selectCountStatus;
        }

        public void setList(List<? extends SelectMoudle> list) {
            this.list = list;
        }

        @NonNull
        @Override
        public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
            if (mContext == null) {
                mContext = parent.getContext();
            }
            MyViewHolder myViewHolder = new MyViewHolder(LayoutInflater.from(mContext).inflate(R.layout.cm_item_select_view, null, false));
            myViewHolder.itemView.setOnClickListener(onClickListener);
            return myViewHolder;
        }

        @Override
        public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
            SelectMoudle selectMoudle = list.get(position);
            holder.itemView.setTag(position);
            holder.name.setText(selectMoudle.getSelectName());
            if (selectMoudle.isSelect()) {
                holder.itemView.setBackgroundColor(selectBgColor);
                holder.name.setTextColor(selectTextColor);
            } else {
                holder.itemView.setBackgroundColor(defaultBgColor);
                holder.name.setTextColor(defaultTextColor);
            }
        }

        @Override
        public int getItemCount() {
            return list == null ? 0 : list.size();
        }

        /**
         * 单选使用
         *
         * @return
         */
        public int getSelectIndex() {
            return mSelectPositon;
        }


        /**
         * 单选使用
         *
         * @return
         */
        public SelectMoudle getSelectMoudle() {
            return list.get(mSelectPositon);
        }

        public List<? extends SelectMoudle> getList() {
            return list;
        }

        private OnClickListener onClickListener = new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (isMultiSelect) {
                    int clickPosition = (int) v.getTag();
                    SelectMoudle nowSelectMoudle = list.get(clickPosition);
                    List<? extends SelectMoudle> childList = nowSelectMoudle.getChildSelectMoudles();
                    if (!nowSelectMoudle.isSelect() &&
                            selectCountStatus.isMax() &&
                            (childList == null || childList.size() <= 0)) {
                        Toast.makeText(mContext, String.format("最多选择%s个", selectCountStatus.getMaxCount()), Toast.LENGTH_SHORT).show();
                        return;
                    }
                    if (childList != null && childList.size() > 0 && !nowSelectMoudle.isSelect()) {
                        nowSelectMoudle.setSelect(true);
                    }
                    mSelectPositon = clickPosition;
                } else {
                    // 处理单选
                    for (SelectMoudle selectMoudle : list) {
                        selectMoudle.setSelect(false);
                    }
                    mSelectPositon = (int) v.getTag();
                    list.get(mSelectPositon).setSelect(true);
                    notifyDataSetChanged();
                }
                myAdapterClickListener.onClick(MyAdapter.this, childIndex, mSelectPositon);
            }
        };
    }

    public static class MyViewHolder extends RecyclerView.ViewHolder {

        TextView name;

        public MyViewHolder(@NonNull View itemView) {
            super(itemView);
            name = itemView.findViewById(R.id.name);
        }
    }


    public interface SelectMoudle {

        String getSelectName();

        List<? extends SelectMoudle> getChildSelectMoudles();

        boolean isIgnoreChilds();

        boolean isSelect();

        void setSelect(boolean isSelect);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
    }

}
